package pais.db;

import java.io.IOException;

import papos.rowset.DuplicatedKeyValueException;
import papos.rowset.KeyNameNotFoundException;
import papos.rowset.StorageSystem;
import pasys.error.PaposException;


public class PAISSystemTable implements TableInterface {
  public static int PAIS_SYSTEM_ID = 1;
  private static PAISSystemTable INST_ = null;

  public static PAISSystemTable createInstance( String path ) {
    assert( INST_ == null );
    INST_ = new PAISSystemTable(path);
    return INST_;
  }
  public static PAISSystemTable getInstance() {
    return INST_;
  }

  private String path_;
  private StorageSystem storage_;
  public PAISSystemTable(String path) {
    path_ = path;
  }

  public void open(boolean writable) throws IOException {
    PAISSystem sampleInstance = new PAISSystem();

    try {
      storage_ = StorageSystem.open(	path_, 
          "pais-system-table", 
          sampleInstance, 
          sampleInstance.getKeyDesc(),
          writable);

      // if the PAISSystem record does not exist, create one.
      if ( getSystem(PAIS_SYSTEM_ID) == null ) {
        createSystem();
      }
    } catch (IOException e) {
      throw e;
    } catch (Exception e) {
      System.out.println(""+e.toString());
      e.printStackTrace();
      System.exit(-1);
    }
  }

  public void sync() throws IOException, PaposException {
    storage_.sync();
  }

  public void close() throws IOException, PaposException  {
    StorageSystem.close(storage_);
    storage_ = null;
  }

  public void createSystem() throws PaposException {
    PAISSystem system = new PAISSystem(PAIS_SYSTEM_ID, 1, 1);
    try {
      if ( !storage_.insert(system) ) {
        assert(false);
      }
    } catch (DuplicatedKeyValueException e) {
      System.out.println(""+e.toString());
      e.printStackTrace();
      System.exit(-1);
    }
  }    

  public PAISSystem getSystem(int systemID) throws PaposException {
    PAISSystem system = new PAISSystem();
    system.setSystemID( systemID );
    try {
      if ( ! storage_.find("systemID_", system) ) {
        return null;
      }
    } catch (KeyNameNotFoundException e) {
      e.printStackTrace();
      PAISDB.exit("PAISSystem Not Found : "+e.toString());
    }
    return system;
  }

  public long updateNextUID() throws PaposException  {
    PAISSystem system = INST_.getSystem(PAIS_SYSTEM_ID);
    long nextUID = system.getNextUID();
    system.setNextUID(nextUID + 1);
    if ( ! storage_.update(system) ) {
      assert(false);
    }
    return nextUID;
  }
  public long updateNextKID() throws PaposException  {
    PAISSystem system = INST_.getSystem(PAIS_SYSTEM_ID);
    long nextKID = system.getNextKID();
    system.setNextKID(nextKID + 1);
    if( ! storage_.update(system) ) {
      assert(false);
    }
    return nextKID;
  }
  public static long getNextUID() throws PaposException {
    return getInstance().updateNextUID();
  }
  public static long getNextKID() throws PaposException  {
    return getInstance().updateNextKID();
  }
}
